const CryptoJS = require('crypto-js')
// 地址下载,fileName暂无作用
export const urlDownload = (url, fileName = '下载文件') => {
  // 创建隐藏的可下载链接
  let eleLink = document.createElement('a')
  eleLink.download = fileName
  eleLink.style.display = 'none'
  eleLink.href = url
  // 触发点击
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然后移除
  document.body.removeChild(eleLink)
}
// 内容转化为文件下载
export const fileDownload = (file, fileName = '下载文件', options) => {
  // 创建隐藏的可下载链接
  let eleLink = document.createElement('a')
  eleLink.download = fileName
  eleLink.style.display = 'none'
  // 字符内容转变成blob地址
  let blob = options ? new Blob([file], options) : new Blob([file])
  eleLink.href = URL.createObjectURL(blob)
  // 触发点击
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然后移除
  document.body.removeChild(eleLink)
}

// 图片压缩
// 接收三个参数：
// file：是读取的文件，需要input type="file"获取或者通过js获取
// rate：压缩比例；按照原来图片的百分比
// maxSize: 压缩后的最大文件
// rate有则使用rate，最大限制拦截，会判断rate后是否大于maxSize，如果大于，则剪切，不大于，这rate
// fileType：返回内容的类型；file即压缩后的第一个参数，blob是blob文件，base64是base64文件
// 返回：promise，第一个参数：filePress，即压缩后的fileType文件；第二个参数：base64，即源文件base64
export const imgPress = ({ file, rate = 1, maxSize = 800, fileType = 'file' }) => {
  return new Promise(resolve => {
    // new一个文件读取方法，监听文件读取
    let reader = new FileReader()
    reader.readAsDataURL(file)
    let img = new Image()
    reader.onload = function (e) {
      img.src = e.target.result
    }
    img.onload = function () {
      let canvas = document.createElement('canvas')
      let context = canvas.getContext('2d')
      // 文件大小KB
      const fileSizeKB = file.size / 1024
      // 配置rate和maxSize的关系
      if (fileSizeKB * rate > maxSize) {
        rate = Math.floor(maxSize / fileSizeKB * 10) / 10
      }
      // 缩放比例，默认0.5
      let targetW = canvas.width = this.width * rate
      let targetH = canvas.height = this.height * rate
      context.clearRect(0, 0, targetW, targetH)
      context.drawImage(img, 0, 0, targetW, targetH)
      if (fileType === 'file' || fileType === 'blob') {
        canvas.toBlob(function (blob) {
          resolve({ filePress: fileType === 'blob' ? blob : new File([blob], file.name, { type: file.type }), base64: img.src })
        })
      } else {
        resolve({ filePress: fileType === 'base64' ? canvas.toDataURL(file.type) : null, base64: img.src })
      }
    }
  })
}

// 过滤element-tree所选中的节点id
export const getIdByTree = (list, target = 'selected', flag = true, returnTarget = 'id') => {
  let idArr = []
  // 深层遍历获取id
  const getId = (arr) => {
    arr.forEach(item => {
      if (item[target] === flag) {
        idArr.push(item[returnTarget])
      }
      if (item.children && item.children.length) {
        getId(item.children)
      }
    })
  }
  getId(list)
  return idArr
}

// 如果你的开发模式(场景)是：将页面拆分为多个组件单独开发，最后通过组装组件完成完整页面逻辑
// validCom、validPage方法你可能会用到
// 使用示例：可参考合同管理、政策管理

// 校验单个组件
// @param refs vue实例$refs引用 （this.$refs）
// @param ref 组件引用名称
// @param emit 子组件组定义输出方法 默认调用 emitComData (需要组件内部提供该方法)
export const validCom = (refs, ref, emit = 'emitComData') => {
  return new Promise(async (resolve, reject) => {
    const valid = await refs[ ref ][ emit ]();
    [false, undefined, null].includes(valid)
      ? reject(new Error(ref)) : resolve(valid)
  })
}
// 校验页面
// @param refs vue实例$refs引用 （this.$refs）
// @param refList 组件引用名称列表
//  形如：[{ ref: 'commonInfo', emit: 'emitComData' }]
export const validPage = (refs, refList) => {
  const iterable = refList.map(item => validCom(refs, item.ref, item.emit))
  return Promise.all(iterable).then(values => {
    return Promise.resolve(values)
  }).catch(err => {
    return Promise.reject(err)
  })
}

// 过滤json数据中的基本数据类型字段
// 使用场景：有些查询详情接口，会一次性返回基本数据和其他组件数据
// 为了减少数据传递，需要手动过滤出基本数据类型的数据
// @param origin 原始数据（obj）
export const filterPrimitive = (origin) => {
  const primitive = {}
  for (let item in origin) {
    if (origin.hasOwnProperty(item) && (origin[ item ] === null || typeof origin[ item ] !== 'object')) {
      primitive[ item ] = origin[ item ]
    }
  }
  return primitive
}
// 接口返回数据判定，接收对象和数组  --- 模拟lodash的hasIn，暂无使用
export function getInUtils(data, arr) {
  let index = 0
  let obj = null
  function isHas(curData, arr) {
    if (curData[arr[index]]) {
      index++
      if (arr.length === index) {
        obj = curData[arr[index - 1]]
      } else {
        isHas(curData[arr[index - 1]], arr)
      }
    }
  }
  isHas(data, arr)
  return obj
}
// 根据特殊标识获取tree节点
// data为：包含该节点的数组，key为：键名，keyVal为：键值
export function getTreeDataByKey(
  data,
  keyVal,
  key = 'id',
  childrenKey = 'children'
) {
  let target = null
  function iterator(data, keyVal, key) {
    for (let i = 0; i < data.length; i++) {
      if (data[i][key] === keyVal) {
        target = data[i]
        break
      } else {
        data[i][childrenKey] && iterator(data[i][childrenKey], keyVal, key)
      }
    }
  }
  iterator(data, keyVal, key)
  return target || {}
}
// 过滤树结构，获取末级节点特定得值
export const getTargetValByKey = (
  list,
  target = 'selected',
  flag = true,
  returnTarget = 'id'
) => {
  let idArr = []
  // 深层遍历获取id
  const getId = arr => {
    arr.forEach(item => {
      if (item[target] === flag) {
        if (item.children && item.children.length) {
          getId(item.children)
        } else {
          idArr.push(item[returnTarget])
        }
      }
    })
  }
  getId(list)
  return idArr
}
// jsx渲染tree的节点类型
export function renderContent(h, {node, data}) {
  if ((data.children && data.children.length) || !data.id) {
    return (
      <span style="flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;">
        <span>
          <span style="margin-right:10px;">{node.label}</span>
          {node.data.type == '1' ? (
            <el-tag size="mini">菜单</el-tag>
          ) : (
            <el-tag type="success" size="mini">
              系统
            </el-tag>
          )}
        </span>
      </span>
    )
  } else {
    return (
      <span style="flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;">
        <span>
          <span style="margin-right:10px;">{node.label}</span>
          {node.data.type == '1' ? (
            <el-tag size="mini">菜单</el-tag>
          ) : node.data.type == '2' ? (
            <el-tag size="mini" type="warning">
              按钮
            </el-tag>
          ) : (
            ''
          )}
        </span>
      </span>
    )
  }
}
// 防抖
export const debounce = (func, wait) => {
  let timeout
  return () => {
    let context = this
    let args = arguments
    if (timeout) clearTimeout(timeout)
    let callNow = !timeout
    timeout = setTimeout(() => {
      timeout = null
    }, wait)
    if (callNow) func.apply(context, args)
  }
}

/**
 * 以iframe的方式实现的多文件下载
 * @param { urls:array } - 需要下载的内容的数组列表,可以只有一条数据。
 */
export const dnLoadMultipleFiles = (urls) => {
  if (typeof urls !== 'object' || urls.length === 0) return
  urls.forEach(item => {
    const iframe = document.createElement('iframe')
    iframe.style.display = 'none' // 防止影响页面
    iframe.style.height = 0 // 防止影响页面
    iframe.src = item
    document.body.appendChild(iframe) // 这一行必须，iframe挂在到dom树上才会发请求
    // 5分钟之后删除（onload方法对于下载链接不起作用，就先这样吧）
    setTimeout(() => {
      iframe.remove()
    }, 5 * 60 * 1000)
  })
}
const key = CryptoJS.enc.Utf8.parse('gkhx_aes_v1_mweb')

// 解密方法
export function Decrypt (word) {
  let decrypt = CryptoJS.AES.decrypt(word, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7})
  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8)
  return decryptedStr.toString()
}
// 加密方法
export function Encrypt (word) {
  let srcs = CryptoJS.enc.Utf8.parse(word)
  let encrypted = CryptoJS.AES.encrypt(srcs, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7})
  return encrypted.toString()
}